package com.liser.print.bluetooth.service;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;

import com.liser.print.bluetooth.callback.ConnectCallback;
import com.liser.print.bluetooth.callback.SendCallback;
import com.liser.print.bluetooth.exceptions.BluetoothException;
import com.liser.print.bluetooth.model.BtConstant;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * 描述：蓝牙设备客户端服务
 *
 * @author zhangqin
 * @date 2018/6/1
 */
public class BtClientService {

    private BluetoothSocket mBluetoothSocket;
    private BluetoothDevice mBluetoothDevice;
    private BluetoothAdapter mBluetoothAdapter;
    private ConnectCallback mConnectCallback;
    public boolean isConnection = false;

    public static BtClientService getInstance() {
        return BtClientServiceHolder.BT_CLIENT_SERVICE;
    }

    private static class BtClientServiceHolder {
        private static final BtClientService BT_CLIENT_SERVICE = new BtClientService();
    }

    /**
     * 初始化
     */
    public void init(BluetoothAdapter bluetoothAdapter, BluetoothDevice device, ConnectCallback connectCallback) {
        mConnectCallback = connectCallback;

        // 已建立过连接
        if (mBluetoothDevice != null) {
            if (mBluetoothDevice.getAddress().equals(device.getAddress())) {
                mConnectCallback.connectSuccess(mBluetoothSocket, mBluetoothDevice);
                return;
            } else {
                cancel();
            }
        }

        mBluetoothAdapter = bluetoothAdapter;
        mBluetoothDevice = device;
        BluetoothSocket tmp = null;
        try {
            //尝试建立安全的连接
            tmp = mBluetoothDevice.createRfcommSocketToServiceRecord(BtConstant.CBT_UUID);
        } catch (IOException e) {
            mConnectCallback.connectError(e);
        }
        mBluetoothSocket = tmp;
        connect();
    }

    private void connect() {
        Observable.create((ObservableOnSubscribe<String>) emitter -> {
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }
            mBluetoothSocket.connect();
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String s) {
                    }

                    @Override
                    public void onError(Throwable e) {
                        mBluetoothAdapter = null;
                        mBluetoothDevice = null;
                        mConnectCallback.connectError(e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    public BluetoothSocket getBluetoothSocket() {
        return mBluetoothSocket;
    }

    /**
     * 发送数据
     */
    public void sendData(final List<byte[]> data, final SendCallback callback) {
        Observable.create((ObservableOnSubscribe<String>) emitter -> {
            OutputStream outputStream = mBluetoothSocket.getOutputStream();
            for (int i = 0; i < data.size(); i++) {
                outputStream.write(data.get(i));
                outputStream.flush();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String s) {
                        callback.sendSuccess();
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.sendError(e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    public Observable<String> sendData(byte[] data) {
        return Observable.create(emitter -> {
            if (!isConnection) {
                emitter.onError(new BluetoothException("设备连接已断开"));
            } else {
                boolean connected = mBluetoothSocket.isConnected();
                OutputStream outputStream = mBluetoothSocket.getOutputStream();
                outputStream.write(data);
                outputStream.flush();
                outputStream.close();
                emitter.onNext(BtConstant.DEFAULT_SUBSCRIBE_MESSAGE);
            }
            emitter.onComplete();
        });
    }

    public void cancel() {
        try {
            mBluetoothSocket.close();
            mBluetoothAdapter = null;
            mBluetoothDevice = null;
            isConnection = false;
        } catch (IOException e) {
        }
    }

    public BluetoothDevice connectedBluetooth() {
        if (mBluetoothSocket == null) {
            return null;
        }
        // 断开连接
        if (!mBluetoothSocket.isConnected()) {
            return null;
        }

        return mBluetoothDevice;
    }
}
